home *** CD-ROM | disk | FTP | other *** search
/ Hot Super Models / Hot Super Models.iso / dos / tif / viewer.c < prev    next >
C/C++ Source or Header  |  1992-07-22  |  57KB  |  2,022 lines

  1. /*  CONDITIONAL COMPILATION FLAGS  */
  2. #define BRUCE   1
  3. #include <dos.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #include <string.h>
  8. #include <sys/time.h>
  9. struct timezone {int hell1; int hell2;};
  10.  
  11. #include "mypow.h"
  12. #include "jinclude.h"
  13. #include "hicolor.h"
  14. #include "viewer.h"
  15. #include "dither.h"
  16. #include "pc.h"
  17. #include "dir.h"
  18. #include "gppconio.h"
  19. #include "grx.h"
  20. #include "grdriver.h"
  21.  
  22. /*
  23.  * Include file for declaring JPEG data structures.
  24.  * This file also includes some system headers like <stdio.h>;
  25.  * if you prefer, you can include "jconfig.h" and "jpegdata.h" instead.
  26.  */
  27.  
  28.  
  29. void targa_input_init (compress_info_ptr cinfo);
  30.  
  31. /*  GLOBALS  */
  32. #ifdef VIEW_DEBUG
  33. int debugrow;
  34. #endif
  35.  
  36. ulong *Buffer0, *Buffer1, *Buffer2; /* buffer to hold one row of pixels */
  37. BYTE ColorLUT[257];
  38. BYTE ColorLUT256[257];
  39. WORD *DispBuf;
  40. char *DispBuf256;
  41. int NewTotal;            /* */
  42. int XOffset, YOffset;
  43. int filerow, endrow, scrrow;
  44. int BytesPerPixel;
  45. long bytesPerRow;
  46. ulong lOffset;
  47. ulong Ytotal;
  48. ulong Yratio, Xratio, InvYratio, InvXratio;
  49. int width;            /* number of pixels to display in a row */
  50. int height;
  51.  
  52. int sameaspectF;
  53. int scaleF, interpF, isbottomupF, ditherF, GinterpF, hicolorF, nohicolor, twopassF,
  54.  blocksmoothF, pixelsmoothF, debugF,old_driversF,timeF,slideF;
  55. int F1024, F800, F640, hi800F, hi640F;
  56. int slidedelay;
  57.  
  58. IMAGE_FORMATS FormatFlag = FMT_JFIF;    /* image file format */
  59. double Gamma;            /* exponent for contrast stretch */
  60. DCtrlType DitherCtrl;
  61. char PB[512];
  62. Files moh_files[MAXFILES];
  63. int totalfiles = 0;
  64. GR_DRIVER_MODE_ENTRY far *ttab, *gtab;
  65. extern JSAMPARRAY gifcolormap;
  66. /*
  67.  * <setjmp.h> is used for the optional error recovery mechanism shown in
  68.  * the second part of the example.
  69.  */
  70.  
  71. #include <setjmp.h>
  72. /******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
  73.  
  74. /* This half of the example shows how to read data from the JPEG decompressor.
  75.  * It's a little more refined than the above in that we show how to do your
  76.  * own error recovery.  If you don't care about that, you don't need these
  77.  * next two routines.
  78.  */
  79.  
  80.  
  81. /*
  82.  * These routines replace the default trace/error routines included with the
  83.  * JPEG code.  The example trace_message routine shown here is actually the
  84.  * same as the standard one, but you could modify it if you don't want messages
  85.  * sent to stderr.  The example error_exit routine is set up to return
  86.  * control to read_JPEG_file() rather than calling exit().  You can use the
  87.  * same routines for both compression and decompression error recovery.
  88.  */
  89.  
  90. /* These static variables are needed by the error routines. */
  91. static jmp_buf setjmp_buffer;    /* for return to caller */
  92. static external_methods_ptr emethods;    /* needed for access to message_parm */
  93.  
  94.  
  95. /* This routine is used for any and all trace, debug, or error printouts
  96.  * from the JPEG code.  The parameter is a printf format string; up to 8
  97.  * integer data values for the format string have been stored in the
  98.  * message_parm[] field of the external_methods struct.
  99.  */
  100.  
  101. METHODDEF void
  102. trace_message (const char *msgtext)
  103. {
  104.   fprintf (stderr, msgtext,
  105.        emethods->message_parm[0], emethods->message_parm[1],
  106.        emethods->message_parm[2], emethods->message_parm[3],
  107.        emethods->message_parm[4], emethods->message_parm[5],
  108.        emethods->message_parm[6], emethods->message_parm[7]);
  109.   fprintf (stderr, "\n");    /* there is no \n in the format string! */
  110. }
  111. /*
  112.  * The error_exit() routine should not return to its caller.  The default
  113.  * routine calls exit(), but here we assume that we want to return to
  114.  * read_JPEG_data, which has set up a setjmp context for the purpose.
  115.  * You should make sure that the free_all method is called, either within
  116.  * error_exit or after the return to the outer-level routine.
  117.  */
  118.  
  119. METHODDEF void
  120. error_exit (const char *msgtext)
  121. {
  122.   trace_message (msgtext);    /* report the error message */
  123.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  124.   longjmp (setjmp_buffer, 1);    /* return control to outer routine */
  125. }
  126.  
  127.  
  128.  
  129. /*
  130.  * To accept the image data from decompression, you must define four routines
  131.  * output_init, put_color_map, put_pixel_rows, and output_term.
  132.  *
  133.  * You must understand the distinction between full color output mode
  134.  * (N independent color components) and colormapped output mode (a single
  135.  * output component representing an index into a color map).  You should use
  136.  * colormapped mode to write to a colormapped display screen or output file.
  137.  * Colormapped mode is also useful for reducing grayscale output to a small
  138.  * number of gray levels: when using the 1-pass quantizer on grayscale data,
  139.  * the colormap entries will be evenly spaced from 0 to MAX_JSAMPLE, so you
  140.  * can regard the indexes are directly representing gray levels at reduced
  141.  * precision.  In any other case, you should not depend on the colormap
  142.  * entries having any particular order.
  143.  * To get colormapped output, set cinfo->quantize_colors to TRUE and set
  144.  * cinfo->desired_number_of_colors to the maximum number of entries in the
  145.  * colormap.  This can be done either in your main routine or in
  146.  * d_ui_method_selection.  For grayscale quantization, also set
  147.  * cinfo->two_pass_quantize to FALSE to ensure the 1-pass quantizer is used
  148.  * (presently this is the default, but it may not be so in the future).
  149.  *
  150.  * The output file writing modules (jwrppm.c, jwrgif.c, jwrtarga.c, etc) may be
  151.  * useful examples of what these routines should actually do, although each of
  152.  * them is encrusted with a lot of specialized code for its own file format.
  153.  */
  154. #ifdef OLD_CODE
  155. void
  156. MakeColorLUT (
  157.            BYTE * pLut,    /* array to hold LUT */
  158.            BYTE minIn,    /* minimum input intensity */
  159.            BYTE maxIn,    /* maximum input intensity */
  160.            BYTE minOut,    /* minimum output intensity */
  161.            BYTE maxOut,    /* maximum output intensity */
  162.            double gamma    /* exponent of stretch */
  163. )
  164. {
  165.   int index;            /* LUT index */
  166.   double scale;            /* scale factor (K) */
  167.   double lutVal;        /* LUT value */
  168.  
  169.   scale = (maxOut - minOut) / pow (maxIn - minIn, gamma);
  170.   for (index = minIn; index <= maxIn; index++)
  171.     {
  172.       lutVal = minOut + scale * pow (index - minIn, gamma);
  173.       *pLut++ = (BYTE) (lutVal + 0.5);
  174.     }
  175. }
  176.  
  177. #endif
  178.  
  179. void
  180. MakeColorLUT (
  181.            BYTE * pLut,    /* array to hold LUT */
  182.            BYTE maxOut,
  183.            double gamma    /* exponent of stretch */
  184. )
  185. {
  186.   int index;            /* LUT index */
  187.   long intgamma;
  188.  
  189.     intgamma=(long) ((1L << PowInfBase)*gamma);    
  190. /*
  191.   scale = (maxOut - minOut) / pow (maxIn - minIn, gamma);
  192. */
  193.   *pLut++ = 0;
  194.   for (index = 1; index <= 255; index++)
  195.     {
  196.       *pLut++ = (BYTE) ((maxOut*mypow(index,intgamma)+(1L << (2*PowInfBase-1)))
  197.                 >> (2*PowInfBase));
  198.     }
  199. }
  200.  
  201.  
  202. METHODDEF void
  203. output_init (decompress_info_ptr cinfo)
  204. /* This routine should do any setup required */
  205. {
  206.   /* This routine can initialize for output based on the data passed in
  207.      cinfo. Useful fields include: image_width, image_height    Pretty
  208.      obvious, I hope. data_precision            bits per pixel value;
  209.      typically 8. out_color_space            output colorspace
  210.      previously requested color_out_comps            number of
  211.      color components in same final_out_comps            number of
  212.      components actually output final_out_comps is 1 if quantize_colors is
  213.      true, else it is equal to color_out_comps.
  214.  
  215.   If you have requested color quantization, the colormap is NOT yet set. You
  216.      may wish to defer output initialization until put_color_map is called. */
  217.  
  218.   int mode = 0x30;
  219.   int w, h;
  220.   ulong *b0, *b1, *b2;
  221.   int i, j, k;
  222.   int numcolors, scrwidth, scrheight;
  223.  
  224.  
  225.  
  226.   if (hicolorF)
  227.     {
  228.       numcolors = 32768;
  229.       BytesPerPixel = 2;
  230.       scrwidth = 640;
  231.       scrheight = 480;
  232.       if ((cinfo->image_width > 640 || cinfo->image_height > 480) && hi800F)
  233.     {
  234.       scrwidth = 800;
  235.       scrheight = 600;
  236.     }
  237.     }
  238.   else
  239.     {
  240.       numcolors = 256;
  241.       BytesPerPixel = 1;
  242.       scrwidth = 640;
  243.       scrheight = 480;
  244.       if ((cinfo->image_width > 640 || cinfo->image_height > 480) && F800)
  245.     {
  246.       scrwidth = 800;
  247.       scrheight = 600;
  248.     }
  249.       if ((cinfo->image_width > 800 || cinfo->image_height > 600) && F1024)
  250.     {
  251.       scrwidth = 1024;
  252.       scrheight = 768;
  253.     }
  254.     }
  255.   bytesPerRow = scrwidth * BytesPerPixel;
  256.   interpF = GinterpF;
  257.   NewTotal = 0;
  258.   Ytotal = 0;
  259.   XOffset = YOffset = 0;
  260.   scrrow = 0;
  261.   filerow = 0;
  262.   Xratio = Yratio = (1L << InflateBase);
  263.   InvXratio = InvYratio = (1L << InflateBase);
  264.   w = cinfo->image_width;
  265.   h = cinfo->image_height;
  266.   if (w > scrwidth)
  267.     {
  268.       Xratio = (w << InflateBase) / (scrwidth);
  269.       InvXratio = (scrwidth << InflateBase) / w;
  270.     }
  271.  
  272.   if (h > scrheight)
  273.     {
  274.       Yratio = (h << InflateBase) / (scrheight);
  275.       InvYratio = (scrheight << InflateBase) / h;
  276.     }
  277.   if (sameaspectF)
  278.     {
  279.       if (Yratio > Xratio)
  280.     {
  281.       Xratio = Yratio;
  282.       InvXratio = InvYratio;
  283.     }
  284.       else
  285.     {
  286.       Yratio = Xratio;
  287.       InvYratio = InvXratio;
  288.     }
  289.     }
  290.   if (!scaleF)
  291.     {
  292.       Xratio = Yratio = (1L << InflateBase);
  293.       InvXratio = InvYratio = (1L << InflateBase);
  294.     }
  295.  
  296.   w = cinfo->image_width * InvXratio;
  297.   h = cinfo->image_height * InvYratio;
  298.   if (w % (1L << InflateBase))
  299.     {
  300.       w = w >> InflateBase;
  301.       w++;
  302.     }
  303.   else
  304.     w = w >> InflateBase;
  305.   if (h % (1L << InflateBase))
  306.     {
  307.       h = h >> InflateBase;
  308.       h++;
  309.     }
  310.   else
  311.     h = h >> InflateBase;
  312.  
  313.   width = (cinfo->image_width * InvXratio) >> InflateBase;
  314.   height = (cinfo->image_width * InvYratio) >> InflateBase;
  315.  
  316.   if (w <= scrwidth)
  317.     XOffset = (scrwidth - w) / 2;
  318.   if (h <= scrheight)
  319.     YOffset = (scrheight - h) / 2;
  320.  
  321.   lOffset = 0xd0200000 + (ulong) YOffset *bytesPerRow + XOffset * BytesPerPixel;
  322.  
  323.  
  324.   endrow = Yratio >> InflateBase;
  325.  
  326.   if (Xratio == (1L << InflateBase) && Yratio == (1L << InflateBase))
  327.     interpF = 0;
  328.  
  329.   if (cinfo->total_passes == IS_BOTTOM_UP)
  330.     {                /* ### kludge for bottom up
  331.                                      targa files */
  332.       lOffset += h * bytesPerRow;
  333.       bytesPerRow = -bytesPerRow;
  334.     }
  335.  
  336.   b0 = Buffer0 = (ulong *) jget_small (sizeof (ulong) * cinfo->image_width);
  337.   b1 = Buffer1 = (ulong *) jget_small (sizeof (ulong) * cinfo->image_width);
  338.   b2 = Buffer2 = (ulong *) jget_small (sizeof (ulong) * cinfo->image_width);
  339.   for (i = 0; i < cinfo->image_width; i++)
  340.     *b0++ = *b1++ = *b2++ = 0;
  341.  
  342.   DispBuf = (WORD *) jget_small (sizeof (WORD) * cinfo->image_width);
  343.   DispBuf256 = (char *) jget_small (sizeof (char) * cinfo->image_width);
  344.  
  345.   if (ditherF)
  346.     if (interpF)
  347.       DitherInit (0, 255, 0, 31, width, &DitherCtrl);
  348.     else
  349.       DitherInit (0, 255, 0, 31, cinfo->image_width, &DitherCtrl);
  350.  
  351.   if (debugF)
  352.     {
  353.       printf ("image : %ld x %ld \n", cinfo->image_width, cinfo->image_height);
  354.       printf ("screen %dx%d\n", scrwidth, scrheight);
  355.       printf ("Xratio: %ld  Yratio: %ld\n", Xratio, Yratio);
  356.       printf ("InvXratio: %ld  InvYratio: %ld\n", InvXratio, InvYratio);
  357.       printf ("screen width %d\n", width);
  358.       if (interpF)
  359.     printf ("interpolating output\n");
  360.       else
  361.     printf ("Not interpolating output\n");
  362.       if (ditherF)
  363.     printf ("dithering output\n");
  364.       else
  365.     printf ("Not dithering output\n");
  366.       printf ("out color space: %d\n", (int) cinfo->out_color_space);
  367.  
  368.       if (getch () == 'q')
  369.     exit (0);
  370.       printf ("ok.\n");
  371.     }
  372. #ifdef VIEW_DEBUG
  373.   if (debugF)  debugrow=0;
  374.   else { 
  375. #endif    
  376.   if (old_driversF)
  377.     GrSetMode (GR_width_height_graphics,
  378.          scrwidth, scrheight);
  379.   else
  380.     GrSetMode (GR_width_height_color_graphics,
  381.          scrwidth, scrheight, numcolors);
  382. /*
  383.   SetVideoMode(mode);
  384. */
  385.   /* my Tseng manual says we should be in 256 */
  386. /*
  387.   SetHicolorMode(mode);
  388. */
  389.   /* color mode before switching to hicolor */
  390. #ifdef VIEW_DEBUG
  391.   }  
  392. #endif
  393. }
  394.  
  395.  
  396. /*
  397.  * This routine is called if and only if you have set cinfo->quantize_colors
  398.  * to TRUE.  It is given the selected colormap and can complete any required
  399.  * initialization.  This call will occur after output_init and before any
  400.  * calls to put_pixel_rows.  Note that the colormap pointer is also placed
  401.  * in a cinfo field, whence it can be used by put_pixel_rows or output_term.
  402.  * num_colors will be less than or equal to desired_number_of_colors.
  403.  *
  404.  * The colormap data is supplied as a 2-D array of JSAMPLEs, indexed as
  405.  *        JSAMPLE colormap[component][indexvalue]
  406.  * where component runs from 0 to cinfo->color_out_comps-1, and indexvalue
  407.  * runs from 0 to num_colors-1.  Note that this is actually an array of
  408.  * pointers to arrays rather than a true 2D array, since C does not support
  409.  * variable-size multidimensional arrays.
  410.  * JSAMPLE is typically typedef'd as "unsigned char".  If you want your code
  411.  * to be as portable as the JPEG code proper, you should always access JSAMPLE
  412.  * values with the GETJSAMPLE() macro, which will do the right thing if the
  413.  * machine has only signed chars.
  414.  */
  415.  
  416. METHODDEF void
  417. put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  418. /* Write the color map */
  419. {
  420.  
  421.   int i;
  422.   JSAMPROW ptr0, ptr1, ptr2;
  423.   /* You need not provide this routine if you always set
  424.      cinfo->quantize_colors FALSE; but a safer practice is to provide it and
  425.      have it just print an error message, like this: */
  426. /*
  427.   fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
  428. */
  429. #ifdef VIEW_DEBUG
  430.     if (debugF) printf("put_color_map called\n");
  431.     else {
  432. #endif
  433.   ptr0 = colormap[0];
  434.   if (cinfo->out_color_space == CS_RGB)
  435.     {
  436.       ptr1 = colormap[1];
  437.       ptr2 = colormap[2];
  438.     }
  439.   else
  440.     ptr1 = ptr2 = ptr0;
  441.  
  442.   for (i = 0; i < num_colors; i++)
  443.     GrSetColor (i, ColorLUT256[*(ptr0++)],
  444.         ColorLUT256[*(ptr1++)], ColorLUT256[*(ptr2++)]);
  445. #ifdef VIEW_DEBUG
  446.   }
  447. #endif        
  448. }
  449.  
  450.  
  451. /*
  452.  * This function is called repeatedly, with a few more rows of pixels supplied
  453.  * on each call.  With the current JPEG code, some multiple of 8 rows will be
  454.  * passed on each call except the last, but it is extremely bad form to depend
  455.  * on this.  You CAN assume num_rows > 0.
  456.  * The data is supplied in top-to-bottom row order (the standard order within
  457.  * a JPEG file).  If you cannot readily use the data in that order, you'll
  458.  * need an intermediate array to hold the image.  See jwrrle.c for an example
  459.  * of outputting data in bottom-to-top order.
  460.  *
  461.  * The data is supplied as a 3-D array of JSAMPLEs, indexed as
  462.  *        JSAMPLE pixel_data[component][row][column]
  463.  * where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
  464.  * num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
  465.  * left edge of image).  Note that this is actually an array of pointers to
  466.  * pointers to arrays rather than a true 3D array, since C does not support
  467.  * variable-size multidimensional arrays.
  468.  * JSAMPLE is typically typedef'd as "unsigned char".  If you want your code
  469.  * to be as portable as the JPEG code proper, you should always access JSAMPLE
  470.  * values with the GETJSAMPLE() macro, which will do the right thing if the
  471.  * machine has only signed chars.
  472.  *
  473.  * If quantize_colors is true, then there is only one component, and its values
  474.  * are indexes into the previously supplied colormap.  Otherwise the values
  475.  * are actual data in your selected output colorspace.
  476.  */
  477.  
  478. #define SRED     GETJSAMPLE(*ptr0)
  479. #define SGREEN   GETJSAMPLE(*ptr1)
  480. #define SBLUE    GETJSAMPLE(*ptr2)
  481.  
  482.  
  483.  
  484. METHODDEF void
  485. put_pixel_rows256 (decompress_info_ptr cinfo, int num_rows,
  486.            JSAMPIMAGE pixel_data)
  487. {
  488.   int col, row;
  489.   JSAMPROW ptr0;
  490.  
  491. #ifdef VIEW_DEBUG
  492.     if (debugF) 
  493.     {
  494.         printf("put_pixel_256 called with %d rows, debugrow %d\n",num_rows,debugrow);
  495.         debugrow+=num_rows;
  496.     }
  497.     else {
  498. #endif
  499.  
  500.   for (row = 0; row < num_rows; row++)
  501.     {
  502.       if (Ytotal <= (NewTotal + (1L << InflateBase)))
  503.     {
  504.  
  505.       ptr0 = pixel_data[0][row];
  506.       if (Xratio != (1L << InflateBase))
  507.         {
  508.           for (col = 0; col < cinfo->image_width; col++)
  509.         {
  510.           DispBuf256[(col * InvXratio + (1L << (InflateBase - 1))) >> InflateBase] =
  511.             *ptr0;
  512.           ptr0++;
  513.         }
  514.           memcpy ((char *) lOffset, DispBuf256, BytesPerPixel * width);
  515.         }            /* for col */
  516.       else
  517.         memcpy ((char *) lOffset, ptr0, BytesPerPixel * width);
  518.  
  519.  
  520.       lOffset += (long) bytesPerRow;
  521.  
  522.  
  523. /*
  524.  
  525.       PutVideoRow30H(NewTotal + YOffset, XOffset, width, DispBuf);
  526. */
  527.       NewTotal += (1L << InflateBase);
  528.       Ytotal += Yratio;
  529.     }
  530.       else
  531.     Ytotal -= (1L << InflateBase);
  532.  
  533.     }                /* for row */
  534. #ifdef VIEW_DEBUG
  535.   }
  536. #endif    
  537. }
  538.  
  539.  
  540.  
  541. METHODDEF void
  542. put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
  543.         JSAMPIMAGE pixel_data)
  544. /* Write some rows of output data */
  545. {
  546.   /* This example shows how you might write full-color RGB data (3
  547.      components) to an output file in which the data is stored 3 bytes per
  548.      pixel. */
  549.   JSAMPROW ptr0, ptr1, ptr2;
  550.   ulong *b0, *b1, *b2;
  551.   int col;
  552.   int row;
  553.   int newrow, mycol;
  554.   ulong temp0, temp1, temp2;
  555.   int endcol, scrcol;
  556.   char r, g, b;
  557.   register
  558.   WORD *pBuf;            /* pointer to video row buffer */
  559.   WORD w0, w1, w2;
  560.   ulong rowfrac, colfrac;
  561.  
  562. /*
  563. printf("got into put_pixel_rows\n");
  564. */
  565. #ifdef VIEW_DEBUG
  566.     if (debugF)
  567.     {
  568.         printf("put_pixel_256 called with %d rows, debugrow %d\n",num_rows,debugrow);
  569.         debugrow+=num_rows;
  570.     }
  571.     else {
  572. #endif
  573.   for (row = 0; row < num_rows; row++)
  574.     {
  575.       if (interpF)
  576.     {
  577.       ptr0 = pixel_data[0][row];
  578.       if (cinfo->out_color_space == CS_RGB)
  579.         {
  580.           ptr1 = pixel_data[1][row];
  581.           ptr2 = pixel_data[2][row];
  582.         }
  583.       else
  584.         ptr1 = ptr2 = ptr0;
  585.       b0 = Buffer0;
  586.       b1 = Buffer1;
  587.       b2 = Buffer2;
  588. /*
  589. printf("filrow: %d endrow: %d\n",filerow,endrow);
  590. */
  591. /*
  592. printf("starting as: %d\n",*ptr0);
  593. */
  594.       if (filerow == endrow)
  595.         {
  596.           endrow = ((scrrow + 2) * Yratio) >> InflateBase;
  597.           rowfrac = ((scrrow + 1) << InflateBase) - filerow * InvYratio;
  598.           for (col = 0; col < cinfo->image_width; col++)
  599.         {
  600.           *b0 += rowfrac * SRED;
  601.           *b1 += rowfrac * SGREEN;
  602.           *b2 += rowfrac * SBLUE;
  603.           b0++;
  604.           b1++;
  605.           b2++;
  606.           ptr0++;
  607.           ptr1++;
  608.           ptr2++;
  609.         }
  610. /*
  611. printf("after row interp: %u\n",*Buffer0);
  612. */
  613.           ptr0 = pixel_data[0][row];
  614.           if (cinfo->out_color_space == CS_RGB)
  615.         {
  616.           ptr1 = pixel_data[1][row];
  617.           ptr2 = pixel_data[2][row];
  618.         }
  619.           else
  620.         ptr1 = ptr2 = ptr0;
  621.           b0 = Buffer0;
  622.           b1 = Buffer1;
  623.           b2 = Buffer2;
  624.           rowfrac = InvYratio - rowfrac;
  625.           endcol = Xratio >> InflateBase;
  626.           scrcol = 0;
  627.           temp0 = temp1 = temp2 = 0;
  628.           for (col = 0; col < cinfo->image_width; col++)
  629.         {
  630.           if (col == endcol)
  631.             {
  632.               endcol = ((scrcol + 2) * Xratio) >> InflateBase;
  633.               colfrac = ((ulong) (scrcol + 1) << InflateBase) - (col * InvXratio);
  634.               temp0 += colfrac * ((*b0 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  635.               temp1 += colfrac * ((*b1 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  636.               temp2 += colfrac * ((*b2 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  637. /*
  638. if (col==1) printf("after col frac: %u wih colfrac %u\n",temp0,colfrac);
  639. */
  640.  
  641.  
  642.               if (!ditherF)
  643.             DispBuf[scrcol] =
  644.               (((WORD) (ColorLUT[(temp0 + (1L << (ColorBase - 1))) >> ColorBase])) << 10 |
  645.                ((WORD) (ColorLUT[(temp1 + (1L << (ColorBase - 1))) >> ColorBase])) << 5 |
  646.                (WORD) (ColorLUT[(temp2 + (1L << (ColorBase - 1))) >> ColorBase]));
  647.               else
  648.             {
  649.               Buffer0[scrcol] = ColorLUT256[(temp0 + (1L << (ColorBase - 1))) >> ColorBase];
  650.               Buffer1[scrcol] = ColorLUT256[(temp1 + (1L << (ColorBase - 1))) >> ColorBase];
  651.               Buffer2[scrcol] = ColorLUT256[(temp2 + (1L << (ColorBase - 1))) >> ColorBase];
  652.             }
  653.  
  654.               colfrac = InvXratio - colfrac;
  655.               temp0 = colfrac * ((*b0 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  656.               temp1 = colfrac * ((*b1 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  657.               temp2 = colfrac * ((*b2 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  658.               scrcol++;
  659.             }
  660.           else
  661.             {
  662.               temp0 += InvXratio * ((*b0 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  663.               temp1 += InvXratio * ((*b1 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  664.               temp2 += InvXratio * ((*b2 + (1L << (InflateBase - BaseDiff - 1))) >> (InflateBase - BaseDiff));
  665. /*
  666. if (!col) printf("after col add: %u\n",temp0);
  667. */
  668.             }
  669.  
  670.           *b0++;
  671.           *b1++;
  672.           *b2++;
  673.           ptr0++;
  674.           ptr1++;
  675.           ptr2++;
  676.         }
  677. /*
  678. printf("after col interp: %u\n",*Buffer0);
  679.  
  680. */
  681.  
  682.           if (ditherF)
  683.         {
  684.           Dither (&DitherCtrl, Buffer0, Buffer0, scrrow % 2);
  685.           Dither (&DitherCtrl, Buffer1, Buffer1, scrrow % 2);
  686.           Dither (&DitherCtrl, Buffer2, Buffer2, scrrow % 2);
  687.           for (col = 0; col < width; col++)
  688.             DispBuf[col] = ((WORD) Buffer0[col] << 10) |
  689.               ((WORD) Buffer1[col] << 5) |
  690.               ((WORD) Buffer2[col]);
  691.         }
  692.  
  693.  
  694.           memcpy ((char *) lOffset, DispBuf, BytesPerPixel * width);
  695.           lOffset += (long) bytesPerRow;
  696.           scrrow++;
  697.  
  698.           b0 = Buffer0;
  699.           b1 = Buffer1;
  700.           b2 = Buffer2;
  701.           ptr0 = pixel_data[0][row];
  702.           if (cinfo->out_color_space == CS_RGB)
  703.         {
  704.           ptr1 = pixel_data[1][row];
  705.           ptr2 = pixel_data[2][row];
  706.         }
  707.           else
  708.         ptr1 = ptr2 = ptr0;
  709.           for (col = 0; col < cinfo->image_width; col++)
  710.         {
  711.           *b0++ = rowfrac * SRED;
  712.           *b1++ = rowfrac * SGREEN;
  713.           *b2++ = rowfrac * SBLUE;
  714.           ptr0++;
  715.           ptr1++;
  716.           ptr2++;
  717.         }
  718.  
  719.         }
  720.       else
  721.         {
  722.           for (col = 0; col < cinfo->image_width; col++)
  723.         {
  724.           *b0 += InvYratio * SRED;
  725.           *b1 += InvYratio * SGREEN;
  726.           *b2 += InvYratio * SBLUE;
  727.           b0++;
  728.           b1++;
  729.           b2++;
  730.           ptr0++;
  731.           ptr1++;
  732.           ptr2++;
  733.         }
  734. /*
  735. printf("after row add: %u\n",*Buffer0);
  736. */
  737.         }
  738.       filerow++;
  739.  
  740.  
  741.     }
  742.       else if (Ytotal <= (NewTotal + (1L << InflateBase)))
  743.     {
  744.  
  745.  
  746.       ptr0 = pixel_data[0][row];
  747.       if (cinfo->out_color_space == CS_RGB)
  748.         {
  749.           ptr1 = pixel_data[1][row];
  750.           ptr2 = pixel_data[2][row];
  751.         }
  752.       else
  753.         ptr1 = ptr2 = ptr0;
  754.       if (ditherF)
  755.         {
  756.           DitherChar (&DitherCtrl, ptr0, ptr0, (NewTotal >> InflateBase) % 2);
  757.           DitherChar (&DitherCtrl, ptr1, ptr1, (NewTotal >> InflateBase) % 2);
  758.           DitherChar (&DitherCtrl, ptr2, ptr2, (NewTotal >> InflateBase) % 2);
  759.           for (col = 0; col < cinfo->image_width; col++)
  760.         DispBuf[(col * InvXratio + (1L << (InflateBase - 1))) >> InflateBase] =
  761.           ((WORD) ptr0[col] << 10) |
  762.           ((WORD) ptr1[col] << 5) |
  763.           ((WORD) ptr2[col]);
  764.         }
  765.       else
  766.         for (col = 0; col < cinfo->image_width; col++)
  767.           {
  768.         DispBuf[(col * InvXratio + (1L << (InflateBase - 1))) >> InflateBase] =
  769.           (((WORD) (ColorLUT[SRED])) << 10 |
  770.            ((WORD) (ColorLUT[SGREEN])) << 5 |
  771.            (WORD) (ColorLUT[SBLUE]));
  772.         ptr0++;
  773.         ptr1++;
  774.         ptr2++;
  775.  
  776.           }            /* for */
  777.  
  778.  
  779.       /* calculate video page and offset */
  780.  
  781.  
  782.       memcpy ((char *) lOffset, DispBuf, BytesPerPixel * width);
  783.       lOffset += (long) bytesPerRow;
  784.  
  785.  
  786. /*
  787.  
  788.       PutVideoRow30H(NewTotal + YOffset, XOffset, width, DispBuf);
  789. */
  790.       NewTotal += (1L << InflateBase);
  791.       Ytotal += Yratio;
  792.     }
  793.       else
  794.     Ytotal -= (1L << InflateBase);
  795.     }
  796. #ifdef VIEW_DEBUG
  797.   }    
  798. #endif    
  799. }
  800.  
  801.  
  802.  
  803. METHODDEF void
  804. output_term (decompress_info_ptr cinfo)
  805. /* Finish up at the end of the output */
  806. {
  807.   /* This termination routine may not need to do anything. */
  808.   /* Note that the JPEG code will only call it during successful exit; */
  809.  
  810.   /* if you want it called during error exit, you gotta do that yourself. */
  811.   DitherTerm (&DitherCtrl);
  812.   (*cinfo->emethods->free_all) ();
  813.  
  814. }
  815.  
  816.  
  817. /*
  818.  * That's it for the routines that deal with writing the output image.
  819.  * Now we have overall control and parameter selection routines.
  820.  */
  821.  
  822.  
  823. /*
  824.  * This routine gets control after the JPEG file header has been read;
  825.  * at this point the image size and colorspace are known.
  826.  * The routine must determine what output routines are to be used, and make
  827.  * any decompression parameter changes that are desirable.  For example,
  828.  * if it is found that the JPEG file is grayscale, you might want to do
  829.  * things differently than if it is color.  You can also delay setting
  830.  * quantize_colors and associated options until this point.
  831.  *
  832.  * j_d_defaults initializes out_color_space to CS_RGB.  If you want grayscale
  833.  * output you should set out_color_space to CS_GRAYSCALE.  Note that you can
  834.  * force grayscale output from a color JPEG file (though not vice versa).
  835.  */
  836.  
  837. METHODDEF void
  838. d_ui_method_selection (decompress_info_ptr cinfo)
  839. {
  840.   /* if grayscale input, force grayscale output; */
  841.   /* else leave the output colorspace as set by main routine. */
  842.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  843.     cinfo->out_color_space = CS_GRAYSCALE;
  844.  
  845.   /* select output routines */
  846.   cinfo->methods->output_init = output_init;
  847.   cinfo->methods->put_color_map = put_color_map;
  848.   if (hicolorF)
  849.     cinfo->methods->put_pixel_rows = put_pixel_rows;
  850.   else
  851.     cinfo->methods->put_pixel_rows = put_pixel_rows256;
  852.   if (ditherF)
  853.     cinfo->use_dithering = TRUE;
  854.   else cinfo->use_dithering = FALSE;
  855.   
  856.   cinfo->methods->output_term = output_term;
  857. }
  858.  
  859.  
  860. /*
  861.  * OK, here is the main function that actually causes everything to happen.
  862.  * We assume here that the JPEG filename is supplied by the caller of this
  863.  * routine, and that all decompression parameters can be default values.
  864.  * The routine returns 1 if successful, 0 if not.
  865.  */
  866.  
  867. GLOBAL int
  868. read_JPEG_file (char *filename)
  869. {
  870.   /* These three structs contain JPEG parameters and working data. They must
  871.      survive for the duration of parameter setup and one call to
  872.      jpeg_decompress; typically, making them local data in the calling
  873.      routine is the best strategy. */
  874.   struct decompress_info_struct cinfo;
  875.   struct decompress_methods_struct dc_methods;
  876.   struct external_methods_struct e_methods;
  877.   /* Select the input and output files. In this example we want to open the
  878.      input file before doing anything else, so that the setjmp() error
  879.      recovery below can assume the file is open. Note that cinfo.output_file
  880.      is only used if your output handling routines use it; otherwise, you can
  881.      just make it NULL. VERY IMPORTANT: use "b" option to fopen() if you are
  882.      on a machine that requires it in order to read binary files. */
  883.  
  884.   if ((cinfo.input_file = fopen (filename, "rb")) == NULL)
  885.     {
  886.       fprintf (stderr, "can't open %s\n", filename);
  887.       return 0;
  888.     }
  889.   cinfo.output_file = NULL;    /* if no actual output file involved */
  890.  
  891.   /* Initialize the system-dependent method pointers. */
  892.   cinfo.methods = &dc_methods;    /* links to method structs */
  893.   cinfo.emethods = &e_methods;
  894.   /* Here we supply our own error handler; compare to use of standard error
  895.      handler in the previous write_JPEG_file example. */
  896.   emethods = &e_methods;    /* save struct addr for possible access */
  897.   e_methods.trace_level = 0;
  898.   e_methods.error_exit = error_exit;    /* supply error-exit routine */
  899.   e_methods.trace_message = trace_message;    /* supply trace-message
  900.                            routine */
  901.  
  902.   /* prepare setjmp context for possible exit from error_exit */
  903.   if (setjmp (setjmp_buffer))
  904.     {
  905.       /* If we get here, the JPEG code has signaled an error. Memory allocation
  906.          has already been cleaned up (see free_all call in error_exit), but we
  907.          need to close the input file before returning. You might also need to
  908.          close an output file, etc. */
  909.       fclose (cinfo.input_file);
  910.       return 0;
  911.     }
  912.   /* Here we use the standard memory manager provided with the JPEG code. In
  913.      some cases you might want to replace the memory manager, or at least the
  914.      system-dependent part of it, with your own code. */
  915.   jselmemmgr (&e_methods);    /* select std memory allocation routines */
  916.   /* If the decompressor requires full-image buffers (for two-pass color
  917.      quantization or a noninterleaved JPEG file), it will create temporary
  918.      files for anything that doesn't fit within the maximum-memory setting.
  919.      You can change the default maximum-memory setting by changing
  920.      e_methods.max_memory_to_use after jselmemmgr returns. On some systems
  921.      you may also need to set up a signal handler to ensure that temporary
  922.      files are deleted if the program is interrupted. (This is most important
  923.      if you are on MS-DOS and use the jmemdos.c memory manager back end; it
  924.      will try to grab extended memory for temp files, and that space will NOT
  925.      be freed automatically.) See jcmain.c or jdmain.c for an example signal
  926.      handler. */
  927.  
  928.   /* Here, set up the pointer to your own routine for post-header-reading
  929.      parameter selection.  You could also initialize the pointers to the
  930.      output data handling routines here, if they are not dependent on the
  931.      image type. */
  932.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  933.  
  934.   /* Set up default decompression parameters. */
  935.   j_d_defaults (&cinfo, TRUE);
  936.   /* TRUE indicates that an input buffer should be allocated. In unusual
  937.      cases you may want to allocate the input buffer yourself; see jddeflts.c
  938.      for commentary. */
  939.  
  940.   /* At this point you can modify the default parameters set by j_d_defaults
  941.      as needed; for example, you can request color quantization or force
  942.      grayscale output.  See jdmain.c for examples of what you might change. */
  943.  
  944.   if (!hicolorF)
  945.     {
  946.       cinfo.quantize_colors = TRUE;
  947.       if (twopassF)
  948.     cinfo.two_pass_quantize = TRUE;
  949.       else
  950.     cinfo.two_pass_quantize = FALSE;
  951.     }
  952.   if (blocksmoothF)
  953.     cinfo.do_block_smoothing = TRUE;
  954.   if (pixelsmoothF)
  955.     cinfo.do_pixel_smoothing = TRUE;
  956.  
  957.  
  958.   /* Set up to read a JFIF or baseline-JPEG file. */
  959.   /* This is the only JPEG file format currently supported. */
  960.   jselrjfif (&cinfo);
  961.  
  962.   /* Here we go! */
  963.   jpeg_decompress (&cinfo);
  964.  
  965.   /* That's it, son.  Nothin' else to do, except close files. */
  966.   /* Here we assume only the input file need be closed. */
  967.   fclose (cinfo.input_file);
  968.  
  969.   return 1;            /* indicate success */
  970.  
  971.   /* Note: if you want to decompress more than one image, we recommend you
  972.      repeat this whole routine.  You MUST repeat the j_d_defaults()/alter
  973.      parameters/jpeg_decompress() sequence, as some data structures allocated
  974.      in j_d_defaults are freed upon exit from jpeg_decompress. */
  975. }
  976.  
  977. void
  978. read_TARGA_file (char *name)
  979. {
  980.   struct compress_info_struct moh_cinfo;
  981.   struct decompress_info_struct moh_dcinfo;
  982.   struct compress_methods_struct moh_c_methods;
  983.   struct external_methods_struct moh_e_methods;
  984.  
  985.   JSAMPARRAY pixel_row;
  986.   int i, j, k;
  987.   JSAMPIMAGE pixel_rows;
  988.  
  989. /* note the similarities here and read_JPEG_file */
  990. /* ## clearly needs modularization */
  991.  
  992.  
  993.   moh_cinfo.methods = &moh_c_methods;
  994.   moh_cinfo.emethods = &moh_e_methods;
  995.   jselerror (&moh_e_methods);    /* error/trace message routines */
  996.   jselmemmgr (&moh_e_methods);    /* memory allocation routines */
  997.  
  998.   if ((moh_cinfo.input_file = fopen (name, "rb")) == NULL)
  999.     {
  1000.       fprintf (stderr, "Can't open %s\n", name);
  1001.       exit (EXIT_FAILURE);
  1002.     }
  1003.  
  1004.   jselrtarga (&moh_cinfo);
  1005.  
  1006.   moh_cinfo.total_passes = 0;
  1007.   (*moh_cinfo.methods->input_init) (&moh_cinfo);
  1008.  
  1009.   /* now to copy the info into a *de*compress info struct, */
  1010.   /* as put_pixel_rows & output_init require that */
  1011.   /* ## I dislike this hack */
  1012.  
  1013.   moh_dcinfo.image_width = moh_cinfo.image_width;
  1014.   moh_dcinfo.image_height = moh_cinfo.image_height;
  1015.   moh_dcinfo.methods = moh_cinfo.methods;
  1016.   moh_dcinfo.emethods = moh_cinfo.emethods;
  1017.  
  1018.   moh_dcinfo.total_passes = moh_cinfo.total_passes;
  1019.   moh_dcinfo.out_color_space = CS_RGB;
  1020.  
  1021.   /* allolcate space for one row of data */
  1022.   pixel_rows = (JSAMPIMAGE) (*moh_cinfo.emethods->alloc_small)
  1023.     (3 * SIZEOF (JSAMPARRAY));
  1024.   pixel_rows[0] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
  1025.     (MAXROWREAD * SIZEOF (JSAMPROW));
  1026.   pixel_rows[1] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
  1027.     (MAXROWREAD * SIZEOF (JSAMPROW));
  1028.   pixel_rows[2] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
  1029.     (MAXROWREAD * SIZEOF (JSAMPROW));
  1030.   for (i = 0; i < 3; i++)
  1031.     {
  1032.       for (j = 0; j < MAXROWREAD; j++)
  1033.     pixel_rows[i][j] = (JSAMPROW)
  1034.       (*moh_cinfo.emethods->alloc_small) (moh_cinfo.image_width * sizeof (JSAMPLE));
  1035.     }
  1036.   pixel_row = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
  1037.     (3 /* moh_cinfo.num_components */ * SIZEOF (JSAMPROW));
  1038.   for (i = 0; i < 3 /* moh_cinfo.num_components */ ; i++)
  1039.     pixel_row[i] = (JSAMPROW) (*moh_cinfo.emethods->alloc_small)
  1040.       (moh_cinfo.image_width * sizeof (JSAMPLE));
  1041. /*
  1042.  
  1043.     pixel_row=(JSAMPIMAGE) malloc(3 *sizeof(JSAMPARRAY));
  1044.     for(i=0;i<3;i++)
  1045.         pixel_row[i]=(JSAMPROW) malloc(sizeof(JSAMPLE)*moh_cinfo.image_width);
  1046. */
  1047.  
  1048.   output_init (&moh_dcinfo);
  1049.   for (i = moh_cinfo.image_height; i;)
  1050.     {
  1051.       k = MIN (i, MAXROWREAD);
  1052.       i -= k;
  1053.       for (j = 0; j < k; j++)
  1054.     {
  1055.       pixel_row[0] = pixel_rows[0][j];
  1056.       pixel_row[1] = pixel_rows[1][j];
  1057.       pixel_row[2] = pixel_rows[2][j];
  1058.       (*moh_cinfo.methods->get_input_row) (&moh_cinfo, pixel_row);
  1059.     }
  1060.       put_pixel_rows (&moh_dcinfo, k, pixel_rows);
  1061.     }
  1062.   /*now to free things */
  1063.   (*moh_cinfo.emethods->free_all) ();
  1064.  
  1065.   fclose (moh_cinfo.input_file);
  1066. }
  1067.  
  1068. void
  1069. read_GIF_file (char *name)
  1070. {
  1071.   struct compress_info_struct moh_cinfo;
  1072.   struct decompress_info_struct moh_dcinfo;
  1073.   struct compress_methods_struct moh_c_methods;
  1074.   struct external_methods_struct moh_e_methods;
  1075.  
  1076.   JSAMPIMAGE pixel_row;
  1077.   JSAMPIMAGE pixel_rows;
  1078.   int i, j, k;
  1079.   int temphicolor, tempdither;
  1080.  
  1081.   temphicolor = hicolorF;
  1082.   tempdither = ditherF;
  1083.  
  1084.   hicolorF = 0;
  1085.   ditherF = 0;
  1086.  
  1087. /* note the similarities here and read_JPEG_file */
  1088. /* ## clearly needs modularization */
  1089.  
  1090.  
  1091.   moh_cinfo.methods = &moh_c_methods;
  1092.   moh_cinfo.emethods = &moh_e_methods;
  1093.   jselerror (&moh_e_methods);    /* error/trace message routines */
  1094.   jselmemmgr (&moh_e_methods);    /* memory allocation routines */
  1095.  
  1096.   if ((moh_cinfo.input_file = fopen (name, "rb")) == NULL)
  1097.     {
  1098.       fprintf (stderr, "Can't open %s\n", name);
  1099.       exit (EXIT_FAILURE);
  1100.     }
  1101.  
  1102.   jselrgif (&moh_cinfo);
  1103.  
  1104.   moh_cinfo.total_passes = 0;
  1105.   (*moh_cinfo.methods->input_init) (&moh_cinfo);
  1106.  
  1107.   /* now to copy the info into a *de*compress info struct, */
  1108.   /* as put_pixel_rows & output_init require that */
  1109.   /* ## I dislike this hack */
  1110.  
  1111.   moh_dcinfo.image_width = moh_cinfo.image_width;
  1112.   moh_dcinfo.image_height = moh_cinfo.image_height;
  1113.   moh_dcinfo.methods = moh_cinfo.methods;
  1114.   moh_dcinfo.emethods = moh_cinfo.emethods;
  1115.  
  1116.   moh_dcinfo.total_passes = moh_cinfo.total_passes;
  1117.   moh_dcinfo.out_color_space = CS_RGB;
  1118.  
  1119.   /* allolcate space for one row of data */
  1120.   pixel_row = (JSAMPIMAGE) (*moh_cinfo.emethods->alloc_small)
  1121.     (1 * SIZEOF (JSAMPARRAY));
  1122.   pixel_row[0] = (JSAMPARRAY) (*moh_cinfo.emethods->alloc_small)
  1123.     (MAXROWREAD * SIZEOF (JSAMPROW));
  1124.   pixel_row[0][0] = (JSAMPROW)
  1125.     (*moh_cinfo.emethods->alloc_small) (moh_cinfo.image_width * sizeof (JSAMPLE));
  1126.  
  1127.   output_init (&moh_dcinfo);
  1128.   put_color_map (&moh_dcinfo, 256, gifcolormap);
  1129.   for (i = moh_cinfo.image_height; i; i--)
  1130.     {
  1131.       (*moh_cinfo.methods->get_input_row) (&moh_cinfo, (JSAMPARRAY) pixel_row);
  1132.       put_pixel_rows256 (&moh_dcinfo, 1, pixel_row);
  1133.  
  1134.     }
  1135.  
  1136.   /*now to free things */
  1137.   (*moh_cinfo.emethods->free_all) ();
  1138.  
  1139.   fclose (moh_cinfo.input_file);
  1140.   hicolorF = temphicolor;
  1141.   ditherF = tempdither;
  1142.  
  1143. }
  1144.  
  1145. void pauseorkey(int delay)
  1146. {
  1147.     int keyhit;
  1148.     
  1149.     keyhit=0;
  1150.     if (delay<0) getch();
  1151.         
  1152.     else while((!keyhit) && (delay>0))
  1153.     {
  1154.         sleep(1);
  1155.         delay--;
  1156.         keyhit=kbhit();
  1157.         if (keyhit) getch();
  1158.     }
  1159. }
  1160.  
  1161.  
  1162. void
  1163. Usage ()
  1164. {
  1165.   fprintf (stderr, "Usage: hiview [options] file ...\n");
  1166.   fprintf (stderr, "   where the options are:\n");
  1167.   fprintf (stderr, "     -d   toggle Floyd-Steinberg dithering, default is off\n");
  1168.   fprintf (stderr, "     -i   toggle smooth interpolation when resizing image, default is on\n");
  1169.   fprintf (stderr, "     -g   GIF format file\n");
  1170.   fprintf (stderr, "     -t   TARGA format file\n");
  1171.   fprintf (stderr, "     -s <gamma>   contrast stretch using exponent gamma\n");
  1172.   fprintf (stderr, "          gamma is a positive double precision number\n");
  1173.   fprintf (stderr, "          values are typically in the range 0.5 .. 1.5\n");
  1174.   fprintf (stderr, "     -q   toggle one/two pass quantization, default is one\n");
  1175.   fprintf (stderr, "     -?   this message\n");
  1176.   fprintf (stderr, "     -D   Debug mode\n");
  1177.   fprintf (stderr, "     -T   Display time of rendering\n");
  1178.   fprintf (stderr, "     -w   Display files as a slide show, infinite delay.\n");
  1179.   fprintf (stderr, "     -W <delay>  Display files as a slide show with <delay> seconds in between.\n");
  1180.   fprintf (stderr, "                 <delay> must be an integer.");
  1181.   
  1182.   fprintf (stderr, "   Filenames may contain wildcards\n");
  1183.   fprintf (stderr, "\n");
  1184. }
  1185.  
  1186.  
  1187. IMAGE_FORMATS
  1188. getformat (char *name)
  1189. {
  1190.   char drive[MAXDRIVE];
  1191.   char dir[MAXDIR];
  1192.   char file[MAXFILE];
  1193.   char ext[MAXEXT];
  1194.   IMAGE_FORMATS type;
  1195.  
  1196.   fnsplit (name, drive, dir, file, ext);
  1197.   if (!strcmp (ext, ".JPG"))
  1198.     type = FMT_JFIF;
  1199.   else if (!strcmp (ext, ".GIF"))
  1200.     type = FMT_GIF;
  1201.   else if (!strcmp (ext, ".TGA"))
  1202.     type = FMT_TARGA;
  1203.   else
  1204.     type = FMT_UNKNOWN;
  1205.   return (type);
  1206. }
  1207. void
  1208. getfiles (char *path, IMAGE_FORMATS ex_type, int level)
  1209. {
  1210.   struct ffblk tempfile;
  1211.   int result;
  1212.   char drive[MAXDRIVE];
  1213.   char dir[MAXDIR];
  1214.   char file[MAXFILE];
  1215.   char ext[MAXEXT];
  1216.   char newpath[500];
  1217.   IMAGE_FORMATS type;
  1218.  
  1219.   result = findfirst (path, &tempfile, 0 | FA_RDONLY | FA_DIREC);
  1220.   type = ex_type;
  1221.   while (result >= 0)
  1222.     {
  1223.       if (!(tempfile.ff_attrib & FA_DIREC))
  1224.     {
  1225.       fnsplit (path, drive, dir, file, ext);
  1226.       strcpy (moh_files[totalfiles].name, drive);
  1227.       strcat (moh_files[totalfiles].name, dir);
  1228.       strcat (moh_files[totalfiles].name, tempfile.ff_name);
  1229.       if (ex_type == FMT_UNKNOWN)
  1230.         type = getformat (moh_files[totalfiles].name);
  1231.       moh_files[totalfiles].type = type;
  1232.       moh_files[totalfiles].selected = 0;
  1233.       totalfiles++;
  1234.       result = findnext (&tempfile);
  1235.     }
  1236.       else
  1237.     {            /* find all *.jpg, gif, tga in directory */
  1238.       fnsplit (path, drive, dir, file, ext);
  1239.       strcpy (newpath, drive);
  1240.       strcat (newpath, dir);
  1241.       strcat (newpath, tempfile.ff_name);
  1242.       result = findnext (&tempfile);
  1243.     }
  1244.     }
  1245. }
  1246.  
  1247. void
  1248. parse_command (int argc, char **argv)
  1249. {
  1250.   struct ffblk tempfile;
  1251.   int result, i, filespec;
  1252.   IMAGE_FORMATS type;
  1253.   char flag;
  1254.  
  1255.   filespec = 0;
  1256.   type = FMT_UNKNOWN;
  1257.   for (i = 1; i < argc; i++)
  1258.     {
  1259.       if (*argv[i] == '-')
  1260.     {
  1261.       flag = *(argv[i] + 1);
  1262.       switch (flag)
  1263.         {
  1264.         case 't':
  1265.           type = FMT_TARGA;
  1266.           break;
  1267.         case 'g':
  1268.           type = FMT_GIF;
  1269.           break;
  1270.         case 'j':
  1271.           type = FMT_JFIF;
  1272.           break;
  1273.         case 'd':
  1274.           ditherF = !ditherF;
  1275.           break;
  1276.         case 'i':
  1277.           GinterpF = !GinterpF;
  1278.           break;
  1279.         case 's':
  1280.           Gamma = atof (argv[++i]);
  1281.           break;
  1282.         case 'h':
  1283.           hicolorF = !hicolorF;
  1284.           break;
  1285.         case 'b':
  1286.           blocksmoothF = !blocksmoothF;
  1287.           break;
  1288.         case 'p':
  1289.           pixelsmoothF = !pixelsmoothF;
  1290.           break;
  1291.         case 'q':
  1292.           twopassF = !twopassF;
  1293.           break;
  1294.         case 'D':
  1295.           debugF = 1;
  1296.           break;
  1297.         case 'T':
  1298.           timeF = 1;
  1299.           break;
  1300.         case 'w':
  1301.           slideF = 1;
  1302.           slidedelay=-1;
  1303.           break;
  1304.         case 'W':
  1305.           slideF = 1;
  1306.           slidedelay = atoi (argv[++i]);
  1307.           break;
  1308.         case '?':
  1309.           Usage ();
  1310.           exit (0);
  1311.           break;
  1312.  
  1313.         }
  1314.     }
  1315.       else
  1316.     {
  1317.       filespec = 1;
  1318.       getfiles (argv[i], type, 0);
  1319.     }
  1320.     }
  1321.  
  1322.   if (!filespec)
  1323.     {
  1324.       getfiles ("*.jpg", FMT_JFIF, 1);
  1325.       getfiles ("*.tga", FMT_TARGA, 1);
  1326.       getfiles ("*.gif", FMT_GIF, 1);
  1327.     }
  1328. }
  1329.  
  1330. void
  1331. draw_border ()
  1332. {
  1333.   int i;
  1334.  
  1335.   gotoxy (1, 1);
  1336.  
  1337.   textbackground (BORDER_BCOLOR);
  1338.   textcolor (BORDER_FCOLOR);
  1339.   for (i = 1; i < SC_WIDTH - 1; i++)
  1340.     cprintf (" ");
  1341.   gotoxy (34, 1);
  1342.   cprintf ("%s v.%s", PROGNAME,VERSION);
  1343.   gotoxy (1, SC_HEIGHT);
  1344.   for (i = 1; i < SC_WIDTH - 1; i++)
  1345.     cprintf (" ");
  1346.   gotoxy (1, SC_HEIGHT - 1);
  1347.   textbackground (MESSAGE_BCOLOR);
  1348.   textcolor (MESSAGE_FCOLOR);
  1349.   cprintf ("%d Files.", totalfiles);
  1350.   gotoxy (40, SC_HEIGHT - 1);
  1351.   textcolor (MESSAGE_HIGHLIGHT);
  1352.   cprintf ("O");
  1353.   textcolor (MESSAGE_FCOLOR);
  1354.   cprintf ("ptions");
  1355.  
  1356.  
  1357. }
  1358.  
  1359. void
  1360. highlight (int fileoffset, int currentpos, int on)
  1361. {
  1362.   int x, y, i, j;
  1363.   int colheight;
  1364.   char drive[MAXDRIVE];
  1365.   char dir[MAXDIR];
  1366.   char file[MAXFILE];
  1367.   char ext[MAXEXT];
  1368.  
  1369.   colheight = SC_HEIGHT - SC_HEADER - SC_FOOTER;
  1370.   x = (SC_WIDTH - SC_COLS * SC_COL_WIDTH) / 2;
  1371.   y = SC_HEADER + 1;
  1372.   i = currentpos - fileoffset;
  1373.   while (i >= colheight)
  1374.     {
  1375.       i -= colheight;
  1376.       x += SC_COL_WIDTH;
  1377.     }
  1378.   y += i;
  1379.   x -= 1;
  1380.  
  1381.   gotoxy (x, y);
  1382.   if (on)
  1383.     {
  1384.       textcolor (FILE_BCOLOR);
  1385.       if (moh_files[currentpos].selected) textcolor(FILE_SELECT);
  1386.       textbackground (FILE_FCOLOR);
  1387.     }
  1388.   else
  1389.     {
  1390.       textbackground (FILE_BCOLOR);
  1391.       if (moh_files[currentpos].selected) textcolor(FILE_SELECT);
  1392.       else textcolor (FILE_FCOLOR);
  1393.     }
  1394.   for (i = 0; i < SC_COL_WIDTH; i++)
  1395.     cprintf (" ");
  1396.   gotoxy (x, y);
  1397.   fnsplit (moh_files[currentpos].name, drive, dir, file, ext);
  1398.  
  1399.   cprintf (" %s", file);
  1400.   gotoxy (x + 10, y);
  1401.   cprintf ("%s ", ext);
  1402.   textbackground (FILE_BCOLOR);
  1403.   textcolor (FILE_FCOLOR);
  1404.  
  1405.  
  1406.  
  1407. }
  1408.  
  1409.  
  1410.  
  1411. void
  1412. print_files (int fileoffset, int currentpos)
  1413. {
  1414.   int i, j, k;
  1415.   int x, y, lastfile;
  1416.   int onscreen;
  1417.   char drive[MAXDRIVE];
  1418.   char dir[MAXDIR];
  1419.   char myfilename[50];
  1420.   char ext[MAXEXT];
  1421.  
  1422.   onscreen = (SC_HEIGHT - SC_HEADER - SC_FOOTER) * SC_COLS;
  1423.  
  1424.   textbackground (FILE_BCOLOR);
  1425.   textcolor (FILE_FCOLOR);
  1426.  
  1427.   for (i = SC_HEADER + 1; i <= SC_HEIGHT - SC_FOOTER; i++)
  1428.     {
  1429.       gotoxy (1, i);
  1430.       clreol ();
  1431.     }
  1432.   x = (SC_WIDTH - SC_COLS * SC_COL_WIDTH) / 2;
  1433.   y = SC_HEADER + 1;
  1434.   lastfile = MIN (totalfiles, onscreen + fileoffset);
  1435.   for (i = fileoffset; i < lastfile; i++)
  1436.     {
  1437.       gotoxy (x, y);
  1438.       fnsplit (moh_files[i].name, drive, dir, myfilename, ext);
  1439.       if (moh_files[i].selected) textcolor(FILE_SELECT);
  1440.       else textcolor(FILE_FCOLOR);
  1441.       cprintf ("%s", myfilename);
  1442.  
  1443.       gotoxy (x + 9, y);
  1444.  
  1445.       cprintf ("%s", ext);
  1446.       y++;
  1447.       if (y > SC_HEIGHT - SC_FOOTER)
  1448.     {
  1449.       x += SC_COL_WIDTH;
  1450.       y = SC_HEADER + 1;
  1451.     }
  1452.     }
  1453.   highlight (fileoffset, currentpos, 1);
  1454. }
  1455.  
  1456. double
  1457. getdouble ()
  1458. {
  1459.   double gamma;
  1460.  
  1461.   scanf ("%lf", &gamma);
  1462.   if (gamma<0) gamma=1;
  1463.   return (gamma);
  1464. }
  1465.  
  1466. void
  1467. optionsmenu ()
  1468. {
  1469.   int quitF = 0;
  1470.   int c;
  1471.  
  1472.   clrscr ();
  1473.   gotoxy (1, SC_HEADER + 1);
  1474.   textbackground (MESSAGE_BCOLOR);
  1475.   textcolor (MESSAGE_HEADER);
  1476.   cprintf ("Global Options: ");
  1477.   gotoxy (1, SC_HEADER + 2);
  1478.   textcolor (MESSAGE_HIGHLIGHT);
  1479.   cprintf ("H");
  1480.   textcolor (MESSAGE_FCOLOR);
  1481.   cprintf ("icolor: ");
  1482.   if (nohicolor)
  1483.     cprintf ("Not available.");
  1484.   else if (hicolorF)
  1485.     cprintf ("Used.");
  1486.   else
  1487.     cprintf ("Not used.");
  1488.   gotoxy (1, SC_HEADER + 3);
  1489.   textcolor (MESSAGE_HIGHLIGHT);
  1490.   cprintf ("B");
  1491.   textcolor (MESSAGE_FCOLOR);
  1492.   cprintf ("lock smoothing: ");
  1493.   if (blocksmoothF)
  1494.     cprintf ("Yes.");
  1495.   else
  1496.     cprintf ("No.");
  1497.  
  1498.   
  1499.   gotoxy (1, SC_HEADER + 4);
  1500.   textcolor (MESSAGE_HIGHLIGHT);
  1501.   cprintf ("P");
  1502.   textcolor (MESSAGE_FCOLOR);
  1503.   cprintf ("ixel smoothing: ");
  1504.   if (pixelsmoothF)
  1505.     cprintf ("Yes.");
  1506.   else
  1507.     cprintf ("No");
  1508.   gotoxy (1, SC_HEADER + 5);
  1509.   textcolor (MESSAGE_HIGHLIGHT);
  1510.   cprintf ("G");
  1511.   textcolor (MESSAGE_FCOLOR);
  1512.   cprintf ("amma: %0.2lf\n", Gamma);
  1513.  
  1514.   gotoxy (1, SC_HEADER + 6);
  1515.   textcolor (MESSAGE_HIGHLIGHT);
  1516.   cprintf ("D");
  1517.   textcolor (MESSAGE_FCOLOR);
  1518.   cprintf ("ithering: ");
  1519.   if (ditherF)
  1520.     cprintf ("Floyd-Steinberg.\n");
  1521.   else
  1522.     cprintf ("None.\n");
  1523.   
  1524.   gotoxy (1, SC_HEADER + 8);
  1525.   textcolor (MESSAGE_HEADER);
  1526.   cprintf ("24->15 bit Options: ");
  1527.   gotoxy (1, SC_HEADER + 9);
  1528.   textcolor (MESSAGE_HIGHLIGHT);
  1529.   cprintf ("I");
  1530.   textcolor (MESSAGE_FCOLOR);
  1531.   cprintf ("nterpolation: ");
  1532.   if (GinterpF)
  1533.     cprintf ("Linear Averaging.\n");
  1534.   else
  1535.     cprintf ("None.\n");
  1536.   gotoxy (1, SC_HEADER + 11);
  1537.   textcolor (MESSAGE_HEADER);
  1538.   cprintf ("24->8 bit Options: ");
  1539.   gotoxy (1, SC_HEADER + 12);
  1540.   textcolor (MESSAGE_HIGHLIGHT);
  1541.   cprintf ("Q");
  1542.   textcolor (MESSAGE_FCOLOR);
  1543.   cprintf ("uantization: ");
  1544.   if (twopassF)
  1545.     cprintf ("Two pass.");
  1546.   else
  1547.     cprintf ("One Pass.");
  1548.   gotoxy (1, SC_HEADER + 14);
  1549.   textcolor (MESSAGE_HEADER);
  1550.   cprintf ("Slide Show Options: ");
  1551.   gotoxy (1, SC_HEADER + 15);
  1552.   textcolor (MESSAGE_FCOLOR);
  1553.   cprintf ("De");
  1554.   textcolor (MESSAGE_HIGHLIGHT);
  1555.   cprintf ("l");
  1556.   textcolor (MESSAGE_FCOLOR);
  1557.   cprintf ("ay: ");
  1558.   if (slidedelay<0)
  1559.         cprintf ("Infinite");
  1560.   else
  1561.     cprintf ("%d seconds.",slidedelay);
  1562.   while (!quitF)
  1563.     {
  1564.       gotoxy (1, SC_HEIGHT - SC_FOOTER - 1);
  1565.       clreol ();
  1566.       cprintf ("Please enter your choice: ");
  1567.       c = getxkey ();
  1568.       switch (c)
  1569.     {
  1570.     case 'i':
  1571.     case 'I':
  1572.       GinterpF = !GinterpF;
  1573.       gotoxy (1, SC_HEADER + 9);
  1574.       clreol ();
  1575.       textcolor (MESSAGE_HIGHLIGHT);
  1576.       cprintf ("I");
  1577.       textcolor (MESSAGE_FCOLOR);
  1578.       cprintf ("nterpolation: ");
  1579.       if (GinterpF)
  1580.         cprintf ("Linear Averaging.\n");
  1581.       else
  1582.         cprintf ("None.\n");
  1583.       clreol ();
  1584.       break;
  1585.     case 'd':
  1586.     case 'D':
  1587.       ditherF = !ditherF;
  1588.       gotoxy (1, SC_HEADER + 6);
  1589.       clreol ();
  1590.       textcolor (MESSAGE_HIGHLIGHT);
  1591.       cprintf ("D");
  1592.       textcolor (MESSAGE_FCOLOR);
  1593.       cprintf ("ithering: ");
  1594.       if (ditherF)
  1595.         cprintf ("Floyd-Steinberg.\n");
  1596.       else
  1597.         cprintf ("None.\n");
  1598.       clreol ();
  1599.       break;
  1600.     case 'g':
  1601.     case 'G':
  1602.       gotoxy (1, SC_HEIGHT - SC_FOOTER - 1);
  1603.       clreol ();
  1604.       cprintf ("Please enter gamma: ");
  1605.       Gamma = getdouble ();
  1606. /*
  1607.       MakeColorLUT (ColorLUT, 0, 255, 0, 31, Gamma);
  1608. */
  1609.       MakeColorLUT (ColorLUT, 31, Gamma);
  1610.       ColorLUT[256] = ColorLUT[255];/* to take care of rounding errors */
  1611. /*
  1612.       MakeColorLUT (ColorLUT256, 0, 255, 0, 255, Gamma);
  1613. */
  1614.       MakeColorLUT (ColorLUT256, 255, Gamma);
  1615.       ColorLUT256[256] = ColorLUT256[255];
  1616.       
  1617.       gotoxy (1, SC_HEADER + 5);
  1618.       clreol ();
  1619.       textcolor (MESSAGE_HIGHLIGHT);
  1620.       cprintf ("G");
  1621.       textcolor (MESSAGE_FCOLOR);
  1622.       cprintf ("amma: %0.2lf\n", Gamma);
  1623.       break;
  1624.     case 'b':
  1625.     case 'B':
  1626.       blocksmoothF = !blocksmoothF;
  1627.       gotoxy (1, SC_HEADER + 3);
  1628.       clreol ();
  1629.       textcolor (MESSAGE_HIGHLIGHT);
  1630.       cprintf ("B");
  1631.       textcolor (MESSAGE_FCOLOR);
  1632.       cprintf ("lock smoothing: ");
  1633.       if (blocksmoothF)
  1634.         cprintf ("Yes.");
  1635.       else
  1636.         cprintf ("No.");
  1637.       break;
  1638.     case 'p':
  1639.     case 'P':
  1640.       pixelsmoothF = !pixelsmoothF;
  1641.       gotoxy (1, SC_HEADER + 4);
  1642.       clreol ();
  1643.       textcolor (MESSAGE_HIGHLIGHT);
  1644.       cprintf ("P");
  1645.       textcolor (MESSAGE_FCOLOR);
  1646.       cprintf ("ixel smoothing: ");
  1647.       if (pixelsmoothF)
  1648.         cprintf ("Yes.");
  1649.       else
  1650.         cprintf ("No");
  1651.       break;
  1652.     case 'q':
  1653.     case 'Q':
  1654.       twopassF = !twopassF;
  1655.       gotoxy (1, SC_HEADER + 12);
  1656.       clreol ();
  1657.       textcolor (MESSAGE_HIGHLIGHT);
  1658.       cprintf ("Q");
  1659.       textcolor (MESSAGE_FCOLOR);
  1660.       cprintf ("uantization: ");
  1661.       if (twopassF)
  1662.         cprintf ("Two pass.");
  1663.       else
  1664.         cprintf ("One Pass.");
  1665.       break;
  1666.     case 'h':
  1667.     case 'H':
  1668.       if (!nohicolor)
  1669.         {
  1670.           hicolorF = !hicolorF;
  1671.           gotoxy (1, SC_HEADER + 2);
  1672.           clreol ();
  1673.           textcolor (MESSAGE_HIGHLIGHT);
  1674.           cprintf ("H");
  1675.           textcolor (MESSAGE_FCOLOR);
  1676.           cprintf ("icolor: ");
  1677.           if (hicolorF)
  1678.         cprintf ("Used.");
  1679.           else
  1680.         cprintf ("Not used.");
  1681.         }
  1682.       break;
  1683.     case 'l': case 'L':
  1684.       gotoxy (1, SC_HEIGHT - SC_FOOTER - 1);
  1685.       clreol ();
  1686.       cprintf ("Please enter delay in seconds (negative number for infinite): ");
  1687.       scanf("%d",&slidedelay);
  1688.       gotoxy (1, SC_HEADER + 15);
  1689.       clreol();
  1690.       textcolor (MESSAGE_FCOLOR);
  1691.       cprintf ("De");
  1692.       textcolor (MESSAGE_HIGHLIGHT);
  1693.       cprintf ("l");
  1694.       textcolor (MESSAGE_FCOLOR);
  1695.       cprintf ("ay: ");
  1696.       if (slidedelay<0)
  1697.         cprintf ("Infinite");
  1698.       else
  1699.       cprintf ("%d seconds.",slidedelay);
  1700.       break;
  1701.     case ESC:
  1702.     case RETURN:
  1703.       quitF = 1;
  1704.       break;
  1705.     }
  1706.     }                /* while */
  1707.  
  1708.  
  1709. }
  1710.  
  1711. void
  1712. userint ()
  1713. {
  1714.   int quitF = 0;
  1715.   int fileoffset = 0;
  1716.   int currentpos = 0;
  1717.   int onscreen;
  1718.   int specialF;
  1719.   int c;
  1720.   int colheight;
  1721.   int sec;
  1722.   int usec;
  1723.   int selected=0;
  1724.   struct timeval tv;
  1725.   struct timezone dummy;
  1726.   int count;
  1727.  
  1728.  
  1729.   colheight = SC_HEIGHT - SC_HEADER - SC_FOOTER;
  1730.   onscreen = colheight * SC_COLS;
  1731.  
  1732.   clrscr ();
  1733.   draw_border ();
  1734.   print_files (fileoffset, currentpos);
  1735.   while (!quitF)
  1736.     {
  1737.       c = getxkey ();
  1738.       switch (c)
  1739.     {
  1740.     case UP:
  1741.       currentpos--;
  1742.       if (currentpos < 0)
  1743.         currentpos = 0;
  1744.       else if (currentpos < fileoffset)
  1745.         {
  1746.           fileoffset--;
  1747.           print_files (fileoffset, currentpos);
  1748.         }
  1749.       else
  1750.         {
  1751.           highlight (fileoffset, currentpos + 1, 0);
  1752.           highlight (fileoffset, currentpos, 1);
  1753.         }
  1754.       break;
  1755.     case DOWN:
  1756.       currentpos++;
  1757.       if (currentpos >= totalfiles)
  1758.         currentpos = totalfiles - 1;
  1759.       else if (currentpos > fileoffset + onscreen - 1)
  1760.         {
  1761.           fileoffset++;
  1762.           print_files (fileoffset, currentpos);
  1763.         }
  1764.       else
  1765.         {
  1766.           highlight (fileoffset, currentpos - 1, 0);
  1767.           highlight (fileoffset, currentpos, 1);
  1768.         }
  1769.       break;
  1770.     case RIGHT:
  1771.       highlight (fileoffset, currentpos, 0);
  1772.       currentpos += colheight;
  1773.       if (currentpos >= totalfiles)
  1774.         currentpos = totalfiles - 1;
  1775.  
  1776.       if (currentpos > fileoffset + onscreen - 1)
  1777.         {
  1778.           fileoffset += colheight;
  1779.           print_files (fileoffset, currentpos);
  1780.         }
  1781.       else
  1782.         {
  1783.           highlight (fileoffset, currentpos, 1);
  1784.         }
  1785.       break;
  1786.     case LEFT:
  1787.       highlight (fileoffset, currentpos, 0);
  1788.       currentpos -= colheight;
  1789.       if (currentpos < 0)
  1790.         currentpos = 0;
  1791.       if (currentpos < fileoffset)
  1792.         {
  1793.           fileoffset -= colheight;
  1794.           if (fileoffset < 0)
  1795.         fileoffset = 0;
  1796.           print_files (fileoffset, currentpos);
  1797.         }
  1798.       else
  1799.         {
  1800.           highlight (fileoffset, currentpos, 1);
  1801.         }
  1802.       break;
  1803.     case 'o':
  1804.     case 'O':
  1805.       optionsmenu ();
  1806.       clrscr ();
  1807.       draw_border ();
  1808.       print_files (fileoffset, currentpos);
  1809.       break;
  1810.     case ESC:
  1811.       return;
  1812.       break;
  1813.     case ' ':
  1814.       moh_files[currentpos].selected=!moh_files[currentpos].selected;
  1815.       if (moh_files[currentpos].selected) selected++;
  1816.       else selected--;
  1817.       currentpos++;
  1818.       if (currentpos >= totalfiles)
  1819.         {
  1820.           currentpos = totalfiles - 1;
  1821.           highlight(fileoffset,currentpos,1);
  1822.         }
  1823.       else if (currentpos > fileoffset + onscreen - 1)
  1824.         {
  1825.           fileoffset++;
  1826.           print_files (fileoffset, currentpos);
  1827.         }
  1828.       else
  1829.         {
  1830.           highlight (fileoffset, currentpos - 1, 0);
  1831.           highlight (fileoffset, currentpos, 1);
  1832.         }
  1833.       break;
  1834.     case RETURN:
  1835.       if (timeF) 
  1836.       {
  1837.         gettimeofday(&tv,&dummy);
  1838.         sec=tv.tv_sec;
  1839.         usec=tv.tv_usec/10000;
  1840.       }
  1841.       if (!selected) moh_files[currentpos].selected=1;
  1842.       for(count=0;count<totalfiles;count++)
  1843.       if (moh_files[count].selected)
  1844.       {
  1845.         switch (moh_files[count].type)
  1846.             {
  1847.             case FMT_JFIF:
  1848.                 read_JPEG_file (moh_files[count].name);
  1849.                 break;
  1850.             case FMT_TARGA:
  1851.                 read_TARGA_file (moh_files[count].name);
  1852.                 break;
  1853.             case FMT_GIF:
  1854.                 read_GIF_file (moh_files[count].name);
  1855.                 break;
  1856.             }
  1857.        if (timeF) 
  1858.         {
  1859.             gettimeofday(&tv,&dummy);
  1860.             sec=tv.tv_sec-sec;
  1861.             usec=tv.tv_usec/10000-usec;
  1862.             if (usec<0) {usec+=100; sec-=1;}
  1863.         }
  1864.        pauseorkey(slidedelay);
  1865.        moh_files[count].selected=0;
  1866.       }
  1867.       selected=0;
  1868.        GrSetMode (GR_80_25_text);
  1869.        if (timeF)
  1870.         {
  1871.             printf("\n\n\n\t It took %d.%d seconds to render\n",sec,usec);
  1872.             getch();
  1873.             clrscr();
  1874.         }
  1875.        draw_border ();
  1876.        print_files (fileoffset, currentpos);
  1877.     
  1878.        break;
  1879.     case 'q':
  1880.       quitF = 1;
  1881.       break;
  1882.     }
  1883.     }                /* while */
  1884. }
  1885.  
  1886.  
  1887. main (int argc, char **argv)
  1888. {
  1889.   char *fname;
  1890.   IMAGE_FORMATS filetype;
  1891.   int i, j, a;
  1892.  
  1893.  
  1894.   timeF=0;
  1895.   debugF = 0;
  1896.   scaleF = 1;
  1897.   sameaspectF = 1;
  1898.   GinterpF = 1;
  1899.   interpF = 1;
  1900.   slideF=0;
  1901.   Gamma = 1.0;
  1902.   slidedelay=-1;
  1903.   blocksmoothF = 0;
  1904.   pixelsmoothF = 0;
  1905.   twopassF = 1;
  1906.   filetype = FMT_JFIF;
  1907.   ditherF = 1;
  1908.   if (debugF)
  1909.     for (i = 0; i < argc; i++)
  1910.       printf ("%s\n", argv[i]);
  1911.   nohicolor = 1;
  1912.  
  1913.   parse_command (argc, argv);
  1914.   if (debugF)
  1915.     {
  1916.       printf ("parsed %d files\n", totalfiles);
  1917.       for (i = 0; i < totalfiles; i++)
  1918.         printf ("%s\n", moh_files[i].name);
  1919.       getch ();
  1920.     }
  1921.   gppconio_init ();
  1922.   if (totalfiles)
  1923.     {
  1924. /*        
  1925.         MakeColorLUT (ColorLUT, 0, 255, 0, 31, Gamma);
  1926. */        
  1927.         MakeColorLUT (ColorLUT, 31, Gamma);
  1928.         ColorLUT[256] = ColorLUT[255];/* to take care of rounding errors */
  1929. /*
  1930.         MakeColorLUT (ColorLUT256, 0, 255, 0, 255, Gamma);
  1931. */
  1932.         MakeColorLUT (ColorLUT256, 255, Gamma);
  1933.         ColorLUT256[256] = ColorLUT256[255];
  1934.         
  1935.         old_driversF=0;
  1936.         GrGetDriverModes (&ttab, >ab);
  1937.         F1024 = F800 = F640 = hi800F = hi640F = 0;
  1938.         if (gtab!=NULL)
  1939.             for (i = 0; gtab[i].width != 0; i++)
  1940.             {
  1941.                 if (gtab[i].number_of_colors == 32768)
  1942.                 nohicolor = 0;
  1943.                 if (gtab[i].width == 1024 && gtab[i].height == 768 &&
  1944.                 gtab[i].number_of_colors == 256)
  1945.                 F1024 = 1;
  1946.                 if (gtab[i].width == 800 && gtab[i].height == 600 &&
  1947.                 gtab[i].number_of_colors == 256)
  1948.                 F800 = 1;
  1949.                 if (gtab[i].width == 640 && gtab[i].height == 480 &&
  1950.                 gtab[i].number_of_colors == 256)
  1951.                 F640 = 1;
  1952.                 if (gtab[i].width == 800 && gtab[i].height == 600 &&
  1953.                 gtab[i].number_of_colors == 32768)
  1954.                 hi800F = 1;
  1955.                 if (gtab[i].width == 640 && gtab[i].height == 480 &&
  1956.                 gtab[i].number_of_colors == 32768)
  1957.                 hi640F = 1;
  1958.             }
  1959.         else
  1960.         {
  1961.             old_driversF=1;            
  1962.             GrSetMode(GR_width_height_graphics,640,480);
  1963.             if (GrSizeX()==640 && GrSizeY()==480) F640=1;
  1964.             if (GrSizeX()==800 && GrSizeY()==600) F800=1;
  1965.             if (GrSizeX()==1024 && GrSizeY()==768) F1024=1;
  1966.             GrSetMode (GR_80_25_text);
  1967.         }
  1968.         if (F640==F1024==F800==hi800F==hi640F==0)
  1969.         {
  1970.             printf("Sorry, Video card not supported.\n");
  1971.             exit(1);
  1972.         }
  1973.       
  1974.       if (nohicolor)
  1975.           hicolorF = 0;
  1976.       else if (hicolorF) hicolorF=0; else hicolorF=1;
  1977.       if (hicolorF) ditherF=!ditherF;
  1978.       if (slideF)
  1979.       {
  1980.         for(i=0;i<totalfiles;i++)
  1981.         {
  1982.         switch (moh_files[i].type)
  1983.             {
  1984.             case FMT_JFIF:
  1985.                 read_JPEG_file (moh_files[i].name);
  1986.                 break;
  1987.             case FMT_TARGA:
  1988.                 read_TARGA_file (moh_files[i].name);
  1989.                 break;
  1990.             case FMT_GIF:
  1991.                 read_GIF_file (moh_files[i].name);
  1992.                 break;
  1993.             }
  1994.          pauseorkey(slidedelay);
  1995.          }
  1996.       }            
  1997.       userint ();
  1998.       GrSetMode (GR_80_25_text);
  1999.     }
  2000.   else printf("No files found");
  2001.   return 0;
  2002. }
  2003.  
  2004. void
  2005. mr_prints (int x, int y, int attr, char *str)
  2006. {
  2007.   while (*str)
  2008.     {
  2009.       if (*str == '\t')
  2010.     x = (x / 8) * 8 + 8;
  2011.       else if (*str == '\n')
  2012.     y++;
  2013.       else
  2014.     ScreenPutChar (*(str++), attr, x++, y);
  2015.       if (x >= 80)
  2016.     {
  2017.       y++;
  2018.       x = 0;
  2019.     }
  2020.     }
  2021. }
  2022.